<template>
  <view class="container">
    <!-- <view class="header">
      <text class="title">游记生成</text>
    </view> -->

    <scroll-view class="content-container" scroll-y>
      <!-- 介绍区域 -->
      <!-- <view class="intro-section">
        <text class="description">智能生成旅游游记，记录您的莒县精彩旅程</text>
      </view> -->
      <view class="my-journal-section" @click="navigateTo('/pages/youji/history')">
        <view class="my-journal-item">
          <text>我的游记</text>
          <text class="my-journal-content">查看您记录的精彩旅程</text>
        </view>
        <uni-icons type="arrowright" size="20" color="#888"></uni-icons>
      </view>

      <!-- 图片设置区域 -->
      <view class="photo-section">
        <text class="section-title">上传旅行照片</text>
        <view class="tips-container">
          <view class="tip-item">
            <uni-icons type="camera" size="20" color="#888"></uni-icons>
            <text class="tip-text">上传清晰的照片可以帮助我们更好地识别景点</text>
          </view>
          <view class="tip-item">
            <uni-icons type="image" size="20" color="#888"></uni-icons>
            <text class="tip-text">建议上传1-3张照片，包含不同的景点和角度</text>
          </view>
        </view>
        <view class="photo-grid">
          <view v-for="(photo, photoIndex) in photos" :key="photoIndex" class="photo-item">
            <image v-if="photo" class="photo-preview" :src="photo.photo" mode="aspectFill" />
            <view v-else class="photo-placeholder" @click="addPhoto(photoIndex)">
              <text class="plus-icon">+</text>
              <text class="upload-text">上传图片</text>
            </view>
            <view v-if="photo && photo.upload_progress" class="photo-progress">
              <text>{{photo.upload_progress}}</text>
            </view>
            <view v-if="photo" class="photo-delete" @click="removePhoto(photoIndex)">
              <text class="delete-icon">×</text>
            </view>
            
          </view>
        </view>
      </view>

      <!-- 旅行体验输入区域 -->
      <view class="experience-section">
        <text class="section-title">旅行体验</text>
        <view class="tips-container">
          <view class="tip-item">
            <uni-icons type="fire" size="20" color="#888"></uni-icons>
            <text class="tip-text">您可以输入描述您的旅行感受和期望</text>
          </view>
          <view class="tip-item">
            <uni-icons type="heart" size="20" color="#888"></uni-icons>
            <text class="tip-text">分享具体的感受可以生成更个性化的游记</text>
          </view>
        </view>
        <view class="voice-input">
          <textarea class="textarea" v-model="experience" placeholder="描述您的旅行体验，例如：我在莒县度过了愉快的两天，参观了浮来山风景区和莒国古城..." />
          <button class="voice-btn" @touchstart.stop.prevent="startVoiceRecord"
            @touchend.stop.prevent="stopVoiceRecord">
            <text class="icon-text">语音输入</text>
          </button>
          <view v-if="isRecording" class="recording-indicator">
            <text>录音中...</text>
          </view>
        </view>
      </view>

      <!-- 生成按钮 -->
      <view class="generate-section">
        <button class="generate-btn" @click="generateJournalMock" :disabled="!canGenerate" :loading="isGenerating">
          <view class="btn-content">
            <text class="btn-text">生成游记</text>
          </view>
        </button>
        <!-- <button class="generate-btn" @click="generateJournal" :disabled="isGenerating || !canGenerate" :class="{'loading': isGenerating}" style="margin-top: 10px;">
          <view v-if="!isGenerating" class="btn-content">
            <text class="btn-text">生成游记</text>
          </view>
          <view v-else class="loading-container">
            <view class="loading-spinner"></view>
            <text class="loading-text">正在生成游记中...</text>
          </view>
        </button> -->
      </view>
    </scroll-view>

    <!-- 游记预览弹窗 -->
    <view class="journal-modal" v-if="showPreview">
      <view class="journal-container">
        <view class="journal-header">
          <text class="journal-title">{{ journalData.title }}</text>
          <text class="journal-close" @click="closePreview">×</text>
        </view>
        <scroll-view class="journal-content" scroll-y>
          <rich-text :nodes="renderMarkdown(journalData.content)" class="markdown-content"></rich-text>
        </scroll-view>
        <view class="journal-actions">
          <button class="journal-btn" @click="saveAsImage">保存为图片</button>
          <button class="journal-btn primary" @click="shareToMoments">分享到朋友圈</button>
        </view>
      </view>
    </view>

    <!-- 添加隐藏canvas用于生成图片 -->
    <!-- 不需要在DOM中创建canvas元素，使用离屏canvas -->
  </view>
</template>

<script>
import { ref, computed, onMounted, reactive } from 'vue'
import { marked } from 'marked';
import { Prism } from 'prismjs';

export default {
  setup() {
    // State
    const isRecording = ref(false);
    const isGenerating = ref(false);
    const showPreview = ref(false);
    const photos = ref([null]); //{photo:data, status:"uploading", url:""}
    const experience = ref('');
    const journalData = reactive({
      title: '',
      content: ''
    });
    const recorderManager = ref(null);
    const generatedContent = ref('');
    const userData = ref(null);

    // Computed properties
    const canGenerate = computed(() => {
      const hasPhotos = photos.value.some(photo => photo !== null);
      const hasExperience = experience.value.trim().length > 0;
      return hasPhotos || hasExperience;
    });

    // Lifecycle hooks
    onMounted(() => {
      initRecorderManager();
      loadUserDataInBackground();
      initMarked();
    });

    // Methods
    function loadUserDataInBackground() {
      try {
        // 从本地获取打卡记录
        const userCheckIns = uni.getStorageSync('user_checkins') || [];

        // 从本地获取聊天历史
        const chatHistory = uni.getStorageSync('chat_history') || [];

        // 将这些数据存储在内存中供后续使用
        userData.value = {
          checkIns: userCheckIns,
          chatHistory: processChatHistory(chatHistory)
        };
      } catch (e) {
        console.error('加载用户数据失败', e);
      }
    }

    function processChatHistory(history) {
      const processedHistory = [];

      for (let i = 0; i < history.length; i++) {
        if (history[i].type === 'user' && i + 1 < history.length && history[i + 1].type === 'assistant') {
          processedHistory.push({
            question: history[i].content,
            answer: history[i + 1].content
          });
        }
      }

      return processedHistory;
    }

    function navigateTo(url) {
      uni.navigateTo({
        url: url
      });
    }

    function initRecorderManager() {
      recorderManager.value = uni.getRecorderManager();

      recorderManager.value.onStop((res) => {
        if (isRecording.value) {
          isRecording.value = false;

          if (res.duration < 1000) {
            uni.showToast({
              title: '说话时间太短',
              icon: 'none'
            });
            return;
          }

          uni.showLoading({
            title: '语音识别中...'
          });

          const token = uni.getStorageSync('token');

          uni.uploadFile({
            url: 'https://tushuoit.com/api/ju/speech-to-text',
            filePath: res.tempFilePath,
            name: 'audio',
            header: {
              Authorization: `Bearer ${token}`
            },
            success: uploadRes => {
              try {
                const data = JSON.parse(uploadRes.data);
                if (data.text) {
                  experience.value += data.text;
                } else {
                  uni.showToast({
                    title: '语音识别失败',
                    icon: 'none'
                  });
                }
              } catch (e) {
                uni.showToast({
                  title: '语音识别结果解析失败',
                  icon: 'none'
                });
              }
            },
            fail: () => {
              uni.showToast({
                title: '语音上传失败',
                icon: 'none'
              });
            },
            complete: () => {
              uni.hideLoading();
            }
          });
        }
      });
    }

    function startVoiceRecord() {
      const token = uni.getStorageSync('token');
      if (!token) {
        uni.showModal({
          title: '提示',
          content: '请先登录后再使用语音功能',
          success: res => {
            if (res.confirm) {
              // 跳转到登录页或显示登录弹窗
            }
          }
        });
        return;
      }

      isRecording.value = true;
      recorderManager.value.start({
        duration: 60000,
        sampleRate: 16000,
        numberOfChannels: 1,
        encodeBitRate: 48000,
        format: 'mp3',
        frameSize: 50
      });
    }

    function stopVoiceRecord() {
      if (isRecording.value) {
        recorderManager.value.stop();
      }
    }

    function uploadPhoto() {
      for (let i = 0; i < photos.value.length; i++) {
        if (photos.value[i].status == "ready") {
          console.log("uploadPhoto:", photos.value[i]);
          photos.value[i].status = "uploading";
          photos.value[i].progress = 0;
          const uploadTask = uni.uploadFile({
            url: 'https://tushuoit.com/api/ju/deepseek/upload',
            filePath: photos.value[i].photo,
            name: 'file',
            formData: {
              apiKey: "juxianwenlv"
            },
            success: res => {
              const data = JSON.parse(res.data);
              console.log("uploadPhoto success:", data);
              photos.value[i].url = data.data.url;
              photos.value[i].status = "uploaded";
              photos.value[i].upload_progress = null;
              console.log("uploadPhoto success:", photos.value[i]);
            },
            fail: () => {
              photos.value[i].status = "failed";
              console.log("uploadPhoto fail:", photos.value[i]);
              photos.value[i].upload_progress = "上传失败";
            },
            complete: () => {
              console.log("uploadPhoto complete:", photos.value[i]);
            }
          });
          uploadTask.onProgressUpdate((res) => {
            console.log('上传进度' + res.progress);
            console.log('已经上传的数据长度' + res.totalBytesSent);
            console.log('预期需要上传的数据总长度' + res.totalBytesExpectedToSend);
            photos.value[i].upload_progress = "上传中:" + res.progress + "%";
          });
        }
      }
    }

    function addPhoto(index) {
      console.log("addPhoto index:", index);
      uni.chooseImage({
        count: 1,
        sizeType: ['compressed'],
        sourceType: ['album', 'camera'],
        success: res => {
          console.log("addPhoto:", res.tempFilePaths.length);
          console.log("addPhoto photos:", photos.value.length);
          photos.value[index] = {photo:res.tempFilePaths[0], status:"ready", url:"", upload_progress:"准备上传"};
          if (index < 2) {
            photos.value.push(null);
          }
          uni.compressImage({
            src: res.tempFilePaths[0],
            quality: 80,
            compressedWidth: 1280,
            format: 'jpeg',
            success: (compressRes) => {
              console.log("compressRes:", compressRes);
              photos.value[index].photo = compressRes.tempFilePath;
            },
            fail: (err) => {
              console.error('Image compression failed:', err);
              // Fallback to original image if compression fails
              photos.value[index].photo = res.tempFilePaths[0]; 
            },
            complete: () => {
              uploadPhoto();
            }
          });
          
        }
      });
    }

    function removePhoto(index) {
      photos.value.splice(index, 1);
      if (photos.value.length == 0) {
        photos.value.push(null);
      }
    }

    function generateJournal() {
      if (!canGenerate.value) {
        uni.showToast({
          title: '请上传照片并描述您的旅行体验',
          icon: 'none'
        });
        return;
      }

      isGenerating.value = true;

      // 构建请求数据
      const token = uni.getStorageSync('token');

      // 准备关于用户的背景数据
      const userCheckInsData = prepareCheckInData();
      const userChatData = prepareChatData();

      // 构建提示词
      const promptData = {
        prompt: `请根据以下信息，为用户生成一篇精彩的莒县旅行游记：
1. 用户的旅行描述：${experience.value || ''}
2. 用户上传的照片数量：${photos.value.filter(Boolean).length}张

${userCheckInsData ? `3. 用户的景点打卡数据：${userCheckInsData}` : ''}
${userChatData ? `4. 用户与智能助手的相关对话：${userChatData}` : ''}

要求：
1. 生成一篇有趣、生动、个人化的旅行游记，字数在800-1200字之间
2. 为游记创建一个吸引人的标题
3. 游记要有明确的开头、中间景点游玩描述、以及结尾感想
4. 在游记中适当位置插入[图片1]、[图片2]等标记，总共插入${Math.min(photos.value.filter(Boolean).length, 6)}个图片标记
5. 语言要生动活泼，细节丰富，包含适当的个人感受和情感表达
6. 适当介绍莒县的历史文化、风土人情和特色美食
7. 格式要美观，使用段落分隔，保持可读性
8. 如果用户提供了特定的体验和感受，要把这些内容融入到游记中
9. 游记开头需要加上"# "开头的一级标题作为游记标题`,
        apiKey: "juxianwenlv",
        stream: true
      };

      // 使用新的API接口，启用分块传输
      const requestTask = uni.request({
        url: 'https://tushuoit.com/api/ju/deepseek/chat',
        method: 'POST',
        enableChunked: true,
        responseType: "text",
        header: {
          'accept': 'application/json',
          'Content-Type': 'application/json',
          'Authorization': token ? `Bearer ${token}` : ''
        },
        data: promptData,
        success: (res) => {
          if (!generatedContent.value || generatedContent.value.trim() === '') {
            uni.showToast({
              title: '游记生成失败',
              icon: 'none'
            });
          } else {
            processGeneratedContent();
          }
        },
        fail: (err) => {
          console.error('请求失败', err);
          uni.showToast({
            title: '网络错误，请重试',
            icon: 'none'
          });
        },
        complete: () => {
          isGenerating.value = false;
        }
      });

      // 初始化生成内容
      generatedContent.value = '';

      // 监听数据块接收事件
      requestTask.onChunkReceived((res) => {
        if (res && res.data) {
          try {
            // 将二进制数据转换为文本
            const uint8Array = new Uint8Array(res.data);
            let text = String.fromCharCode.apply(null, uint8Array);
            text = decodeURIComponent(escape(text));

            // 处理SSE数据块
            const lines = text.split('\n');
            for (const line of lines) {
              if (line.startsWith('data: ')) {
                // 过滤结束标记
                if (line === 'data: [DONE]') continue;

                const jsonData = line.substring(6); // 移除 "data: " 前缀
                try {
                  const data = JSON.parse(jsonData);
                  // 处理OpenAI/DeepSeek格式的流式响应
                  if (data.choices && data.choices[0]) {
                    if (data.choices[0].delta && data.choices[0].delta.content) {
                      // 将新的内容部分添加到当前消息中
                      const chunk = data.choices[0].delta.content;
                      generatedContent.value += chunk;
                    }
                    // 可能有些API返回格式略有不同
                    else if (data.choices[0].message && data.choices[0].message.content) {
                      const chunk = data.choices[0].message.content;
                      generatedContent.value += chunk;
                    }
                  }
                  // 处理其他可能的格式
                  else if (data.data && data.data.text) {
                    generatedContent.value += data.data.text;
                  }
                } catch (e) {
                  console.error('解析JSON块失败', e, jsonData);
                }
              }
            }
          } catch (e) {
            console.error('处理数据块失败', e);
          }
        }
      });
    }

    function processGeneratedContent() {
      let content = generatedContent.value;
      let title = '我的莒县之旅';

      const titleMatch = content.match(/^#\s+(.+?)(?:\n|$)/);
      if (titleMatch) {
        title = titleMatch[1].trim();
        content = content.substring(titleMatch[0].length).trim();
      }

      const validPhotos = photos.value.filter(Boolean);
      for (let i = 0; i < validPhotos.length; i++) {
        const placeholder = `[图片${i + 1}]`;
        const markdownImage = `\n\n![游记照片${i + 1}](${validPhotos[i]})\n\n`;
        content = content.replace(placeholder, markdownImage);
      }

      journalData.title = title;
      journalData.content = content;

      showPreview.value = true;
    }

    function prepareCheckInData() {
      if (!userData.value || !userData.value.checkIns || userData.value.checkIns.length === 0) {
        return null;
      }

      const recentCheckIns = userData.value.checkIns.slice(0, 5);

      return recentCheckIns.map(item =>
        `打卡地点：${item.name}，时间：${item.checkInTime}`
      ).join('\n');
    }

    function prepareChatData() {
      if (!userData.value || !userData.value.chatHistory || userData.value.chatHistory.length === 0) {
        return null;
      }

      const relevantChats = userData.value.chatHistory
        .filter(chat => isTravelRelated(chat.question))
        .slice(0, 5);

      if (relevantChats.length === 0) {
        return null;
      }

      return relevantChats.map(chat =>
        `问：${chat.question}\n答：${truncateText(chat.answer, 100)}`
      ).join('\n\n');
    }

    function isTravelRelated(text) {
      const keywords = ['莒县', '旅游', '景点', '游玩', '打卡', '风景', '文化', '历史', '美食'];
      return keywords.some(keyword => text.includes(keyword));
    }

    function truncateText(text, maxLength) {
      if (text.length <= maxLength) return text;
      return text.substring(0, maxLength) + '...';
    }

    function closePreview() {
      showPreview.value = false;
    }

    function saveAsImage() {
      uni.showLoading({
        title: '生成图片中...'
      });

      try {
        // 获取系统信息以确定画布大小
        const sysInfo = uni.getSystemInfoSync();
        const canvasWidth = sysInfo.windowWidth;
        const canvasHeight = 800; // 固定高度，可根据需要调整

        // 创建离屏canvas
        const canvas = uni.createOffscreenCanvas({
          type: '2d',
          width: canvasWidth,
          height: canvasHeight
        });

        // 获取context
        const ctx = canvas.getContext('2d');
        if (!ctx) {
          throw new Error('无法获取canvas context');
        }

        // 绘制白色背景
        ctx.fillStyle = '#ffffff';
        ctx.fillRect(0, 0, canvasWidth, canvasHeight);

        // 绘制标题
        ctx.fillStyle = '#333333';
        ctx.font = 'bold 20px sans-serif';
        ctx.textAlign = 'center';
        ctx.fillText(journalData.title, canvasWidth / 2, 40);

        // 绘制文本内容
        ctx.textAlign = 'left';
        ctx.font = '14px sans-serif';

        // 分段处理内容
        const contentText = journalData.content.replace(/!\[.*?\]\(.*?\)/g, ''); // 移除图片标记
        const paragraphs = contentText.split('\n\n');
        let y = 80;

        // 绘制文本
        for (const paragraph of paragraphs) {
          if (paragraph.trim()) {
            const maxWidth = canvasWidth - 40;
            const lines = [];

            // 简单计算文本换行
            let currentLine = '';
            const words = paragraph.split(' ');

            for (const word of words) {
              const testLine = currentLine + word + ' ';
              const metrics = ctx.measureText(testLine);

              if (metrics.width > maxWidth && currentLine) {
                lines.push(currentLine.trim());
                currentLine = word + ' ';
              } else {
                currentLine = testLine;
              }
            }

            if (currentLine.trim()) {
              lines.push(currentLine.trim());
            }

            // 如果没有空格，强制分割
            if (lines.length === 0) {
              let line = '';
              for (let i = 0; i < paragraph.length; i++) {
                const char = paragraph[i];
                const testLine = line + char;
                const metrics = ctx.measureText(testLine);

                if (metrics.width > maxWidth && line) {
                  lines.push(line);
                  line = char;
                } else {
                  line = testLine;
                }
              }

              if (line) {
                lines.push(line);
              }
            }

            // 绘制段落的每一行
            for (const line of lines) {
              ctx.fillText(line, 20, y);
              y += 20;
            }

            y += 10; // 段落间距
          }
        }

        // 添加图片（如果有）
        async function addImages() {
          const validPhotos = photos.value.filter(Boolean);

          // 如果没有图片，直接生成结果
          if (validPhotos.length === 0) {
            generateFinalImage();
            return;
          }

          let imageY = y + 20;
          const imageHeight = 150;
          let loadedImages = 0;

          for (let i = 0; i < Math.min(validPhotos.length, 3); i++) { // 最多处理3张图片
            try {
              // 创建图片并加载
              const img = canvas.createImage();

              // 设置图片加载完成事件
              img.onload = () => {
                try {
                  // 计算图片宽度，保持比例
                  const imgWidth = Math.min(canvasWidth - 40, imageHeight * (img.width / img.height));
                  // 绘制图片
                  ctx.drawImage(img, (canvasWidth - imgWidth) / 2, imageY, imgWidth, imageHeight);
                  imageY += imageHeight + 20;

                  // 当所有图片加载完成后，生成最终图片
                  loadedImages++;
                  if (loadedImages === Math.min(validPhotos.length, 3)) {
                    generateFinalImage();
                  }
                } catch (err) {
                  console.error('绘制图片失败', err);
                  // 继续处理其他图片
                  loadedImages++;
                  if (loadedImages === Math.min(validPhotos.length, 3)) {
                    generateFinalImage();
                  }
                }
              };

              // 设置图片加载失败事件
              img.onerror = () => {
                console.error('图片加载失败');
                // 继续处理其他图片
                loadedImages++;
                if (loadedImages === Math.min(validPhotos.length, 3)) {
                  generateFinalImage();
                }
              };

              // 设置图片源
              img.src = validPhotos[i];
            } catch (err) {
              console.error('处理图片失败', err);
              // 继续处理其他图片
              loadedImages++;
              if (loadedImages === Math.min(validPhotos.length, 3)) {
                generateFinalImage();
              }
            }
          }

          // 如果图片加载过程中出错，确保在超时后仍能生成图片
          setTimeout(() => {
            if (loadedImages < Math.min(validPhotos.length, 3)) {
              console.warn('部分图片未成功加载，继续生成图片');
              generateFinalImage();
            }
          }, 3000);
        }

        // 生成最终图片并保存
        function generateFinalImage() {
          try {
            // 从canvas获取图片
            const tempFilePath = canvas.toDataURL();

            // base64转为本地临时文件
            const fs = uni.getFileSystemManager();
            const tempPath = `${uni.env.USER_DATA_PATH}/journal_image_${Date.now()}.png`;

            fs.writeFileSync(
              tempPath,
              tempFilePath.replace(/^data:image\/\w+;base64,/, ''),
              'base64'
            );

            // 保存到相册
            uni.saveImageToPhotosAlbum({
              filePath: tempPath,
              success: () => {
                uni.hideLoading();
                uni.showToast({
                  title: '已保存到相册',
                  icon: 'success'
                });
              },
              fail: (err) => {
                handleSaveError(err);
              }
            });
          } catch (err) {
            console.error('生成图片失败', err);
            uni.hideLoading();
            uni.showToast({
              title: '生成图片失败',
              icon: 'none'
            });
          }
        }

        // 开始处理图片
        addImages();

      } catch (err) {
        console.error('Canvas 操作失败', err);
        uni.hideLoading();
        uni.showToast({
          title: '生成图片失败',
          icon: 'none'
        });
      }
    }

    // 处理保存错误
    function handleSaveError(err) {
      console.error('保存相册失败', err);
      uni.hideLoading();

      // 如果是权限问题，引导用户开启权限
      if (err.errMsg && (err.errMsg.indexOf('auth deny') >= 0 || err.errMsg.indexOf('authorize') >= 0)) {
        uni.showModal({
          title: '提示',
          content: '需要授权保存到相册',
          success: (modalRes) => {
            if (modalRes.confirm) {
              uni.openSetting();
            }
          }
        });
      } else {
        uni.showToast({
          title: '保存失败',
          icon: 'none'
        });
      }
    }

    // 将文本分割成多行
    function splitTextToLines(text, maxWidth, context) {
      const lines = [];
      let currentLine = '';

      // 按照空格分割单词
      const words = text.split(' ');

      for (let i = 0; i < words.length; i++) {
        const word = words[i];
        const testLine = currentLine + word + ' ';
        const metrics = context.measureText(testLine);
        const testWidth = metrics.width;

        if (testWidth > maxWidth && currentLine !== '') {
          lines.push(currentLine.trim());
          currentLine = word + ' ';
        } else {
          currentLine = testLine;
        }
      }

      if (currentLine.trim()) {
        lines.push(currentLine.trim());
      }

      // 如果没有空格，强制分割
      if (lines.length === 0) {
        let line = '';
        for (let i = 0; i < text.length; i++) {
          const char = text[i];
          const testLine = line + char;
          const testWidth = context.measureText(testLine).width;

          if (testWidth > maxWidth && line !== '') {
            lines.push(line);
            line = char;
          } else {
            line = testLine;
          }
        }

        if (line) {
          lines.push(line);
        }
      }

      return lines;
    }

    function shareToMoments() {
      uni.showLoading({
        title: '准备分享图片...'
      });

      const token = uni.getStorageSync('token');

      // 使用uni.request替代uni.downloadFile，并设置responseType为arraybuffer来接收二进制数据
      uni.request({
        url: 'https://tushuoit.com/api/ju/deepseek/markdown/to/image',
        method: 'POST',
        responseType: 'arraybuffer',  // 设置为接收二进制数据
        header: {
          'Content-Type': 'application/json',
          'Authorization': token ? `Bearer ${token}` : ''
        },
        data: {
          markdown: `# ${journalData.title}\n\n${journalData.content}`,
          apiKey: 'juxianwenlv',
          style: {
            background: '#ffffff',
            titleColor: '#333333',
            textColor: '#666666',
            fontFamily: 'Arial, sans-serif'
          },
          format: 'png'
        },
        success: (res) => {
          if (res.statusCode === 200 && res.data) {
            try {
              // 保存二进制数据到临时文件
              const fs = uni.getFileSystemManager();
              const tempFilePath = `${uni.env.USER_DATA_PATH}/share_image_${Date.now()}.png`;

              fs.writeFile({
                filePath: tempFilePath,
                data: res.data,
                encoding: 'binary',
                success: () => {
                  // 将临时文件保存到相册
                  uni.saveImageToPhotosAlbum({
                    filePath: tempFilePath,
                    success: () => {
                      uni.hideLoading();
                      uni.showModal({
                        title: '分享提示',
                        content: '图片已保存到相册，可到微信朋友圈选择分享',
                        showCancel: false
                      });
                    },
                    fail: (err) => {
                      handleSaveError(err);
                    }
                  });
                },
                fail: (err) => {
                  console.error('文件写入失败', err);
                  uni.hideLoading();
                  uni.showToast({
                    title: '保存图片失败',
                    icon: 'none'
                  });
                }
              });
            } catch (err) {
              console.error('处理图片数据失败', err);
              uni.hideLoading();
              uni.showToast({
                title: '处理图片失败',
                icon: 'none'
              });
            }
          } else {
            uni.hideLoading();
            uni.showToast({
              title: '生成图片失败',
              icon: 'none'
            });
          }
        },
        fail: (err) => {
          console.error('请求失败', err);
          uni.hideLoading();
          uni.showToast({
            title: '网络请求失败',
            icon: 'none'
          });
        }
      });
    }

    function initMarked() {
      marked.setOptions({
        renderer: new marked.Renderer(),
        highlight: function (code, lang) {
          if (Prism.languages[lang]) {
            return Prism.highlight(code, Prism.languages[lang], lang);
          } else {
            return code;
          }
        },
        pedantic: false,
        gfm: true,
        breaks: true,
        sanitize: false,
        smartLists: true,
        smartypants: false,
        xhtml: false
      });
    }

    function renderMarkdown(content) {
      try {
        if (!content) return '';

        let html = marked.parse(content);

        return html;
      } catch (error) {
        console.error('Markdown渲染失败:', error);
        return content;
      }
    }

    function objectToQueryString(obj) {
      return Object.keys(obj)
        .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`)
        .join("&");
    }

    // 模拟生成游记并跳转到详情页
    async function generateJournalMock() {
      if (!canGenerate.value) {
        uni.showToast({
          title: '请上传照片并描述您的旅行体验',
          icon: 'none'
        });
        return;
      }

      uni.showLoading({
        title: '正在生成游记...'
      });
      isGenerating.value = true;
      try {
        // 获取用户信息
        const userInfo = uni.getStorageSync('userInfo') || {};
        const username = userInfo.username || '游客';
        const unionId = userInfo.openId || '';

        // 准备上传的图片
        var validPhotos = [];
        photos.value.forEach(photo => {
          if (photo && photo.url) {
            validPhotos.push(photo.url);
          }
        })
        if (validPhotos.length === 0) {
          throw new Error('请至少上传一张照片');
        }

        var img_urls = '';
        validPhotos.forEach(photo => {
          img_urls+=`&img_urls=${encodeURIComponent(photo)}`;
        })

        // 构建URL参数
        const params = {
          username: username,
          union_id: unionId,
          user_desc: experience.value || '这是我去莒县游玩的图片',
          topic: '轻松快活',
          today: new Date().toISOString().split('T')[0].replace(/-/g, ''),
          use_stream: 'false',
          model: 'deepseek-v3',
          temperature: '0.2',
          max_tokens: '300'
        };

        const queryString = objectToQueryString(params);

        // 构建完整的URL
        const baseUrl = 'https://tushuoit.com/api/ju/travel_share/generate/report';
        const url = `${baseUrl}?${queryString}${img_urls}`;

        uni.request({
          url: url,
          method: 'POST',
          data: {
            api_key: 'juxianwenlv'
          },
          success: (res) => {
            console.log("res:", res);
            uni.hideLoading();
            isGenerating.value = false;
            photos.value = [null];
            experience.value = '';
            uni.navigateTo({
              url: `/pages/youji/detail?travel_id=${res.data.report_id}`
            });
          },
          fail: (err) => {
            console.error('请求失败', err);
            uni.hideLoading();
            isGenerating.value = false;
            uni.showToast({
              title: '请求失败',
              icon: 'none'
            });
          }
        });
        

      } catch (error) {
        uni.showToast({
          title: error.message || '生成游记失败',
          icon: 'none'
        });
        isGenerating.value = false;
        uni.hideLoading();
      } finally {
      }
    }

    // Return all data and methods that will be used in the template
    return {
      isRecording,
      isGenerating,
      showPreview,
      photos,
      experience,
      journalData,
      canGenerate,
      startVoiceRecord,
      stopVoiceRecord,
      addPhoto,
      removePhoto,
      generateJournal,
      closePreview,
      saveAsImage,
      splitTextToLines, // Only include methods that exist
      shareToMoments,
      renderMarkdown,
      generateJournalMock,
      navigateTo,
      // Removed processContentForCanvas since it doesn't exist
    };
  }
};
</script>

<style>
.container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background-color: #f8f0e3;
}

.header {
  padding: 20px;
  background-color: #d9b38c;
}

.title {
  font-size: 24px;
  font-weight: bold;
  color: #333;
}

.content-container {
  flex: 1;
  /* Removed horizontal padding, keeping only bottom padding */
}

.intro-section {
  padding: 15px 0;
  text-align: center;
}

.my-journal-section {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 30rpx;
  background-color: #fff;
  margin: 40rpx 30rpx 0 30rpx;
  text-align: center;
  border-radius: 10px;
}

.my-journal-item {
  display: flex;
  align-items: center;
  font-size: 18px;
  font-weight: bold;
  color: #333;
}

.my-journal-content {
  font-size: 14px;
  margin-left: 20rpx;
  color: #999;
}

.description {
  font-size: 16px;
  color: #666;
}

/* 照片区域样式 */
.photo-section {
  background-color: #fff;
  border-radius: 10px;
  padding: 15px;
  margin: 30rpx 30rpx 0 30rpx;
  /* Added horizontal margin instead of padding */
}

.section-title {
  font-size: 18px;
  font-weight: bold;
  color: #333;
}

.tips-container {
  background-color: #f0e0d0;
  border-radius: 16rpx;
  margin-top: 20rpx;
  padding: 16rpx;
}

.tip-item {
  display: flex;
  align-items: center;
}

.tip-text {
  margin-left: 10rpx;
  font-size: 12px;
  color: #666;
}

.photo-grid {
  display: flex;
  /* justify-content: space-between; */
  margin-top: 20rpx;
}

.photo-item {
  width: 32%;
  height: 100px;
  position: relative;
  margin-right: 10px;
}

.photo-preview {
  width: 100%;
  height: 100%;
  border-radius: 8px;
  object-fit: cover;
}

.photo-placeholder {
  width: 100%;
  height: 100%;
  background-color: #f9f5f0;
  border: 1px dashed #d9b38c;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  border-radius: 8px;
}

.plus-icon {
  font-size: 24px;
  color: #d9b38c;
  margin-bottom: 4px;
}

.upload-text {
  font-size: 12px;
  color: #999;
}

.uploading-indicator {
  
  font-size: 12px;
  color: #ff4d4f;
  background-color: rgba(0, 0, 0, 0.5);
}
.photo-progress {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  color: #fff;
  display: flex;
  justify-content: center;
  align-items: center;
}

.photo-delete {
  position: absolute;
  top: -8px;
  right: -8px;
  width: 22px;
  height: 22px;
  background-color: rgba(255, 0, 0, 0.7);
  color: white;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.delete-icon {
  font-size: 16px;
}

/* 体验输入区域样式 */
.experience-section {
  background-color: #fff;
  border-radius: 10px;
  padding: 15px;
  margin: 30rpx 30rpx 0 30rpx;
  /* Added horizontal margin instead of padding */
}

.voice-input {
  position: relative;
}

.textarea {
  width: calc(100% - 24rpx);
  height: 120px;
  border: 1px solid #d9b38c;
  border-radius: 5px;
  padding: 12rpx;
  /* Restored the padding that was commented out */
  background-color: #f9f5f0;
  margin-top: 20rpx;
}

.voice-btn {
  position: absolute;
  right: 10px;
  bottom: 10px;
  width: 80px;
  height: 30px;
  font-size: 12px;
  background-color: #8b6b4a;
  color: white;
  border-radius: 15px;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 0;
}

.recording-indicator {
  position: absolute;
  right: 10px;
  bottom: -25px;
  font-size: 12px;
  color: #ff4d4f;
}

/* 生成按钮样式 */
.generate-section {
  margin: 30rpx 30rpx 0 30rpx;
  /* Keep horizontal padding for the button */
}

.generate-btn {
  background-color: #8b6b4a;
  color: white;
  height: 45px;
  border-radius: 22.5px;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  overflow: hidden;
  transition: background-color 0.3s;
}

.generate-btn.loading {
  background-color: #9c7b5a;
}

.generate-btn:disabled {
  background-color: #ccc;
  opacity: 0.7;
}

.btn-content {
  display: flex;
  align-items: center;
  justify-content: center;
}

.btn-text {
  font-size: 16px;
  font-weight: bold;
}

/* Loading styles */
.loading-container {
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #8b6b4a;
}

.loading-spinner {
  width: 24px;
  height: 24px;
  border: 3px solid rgba(255, 255, 255, 0.3);
  border-top-color: #ffffff;
  border-radius: 50%;
  margin-right: 10px;
  animation: spin 0.8s linear infinite;
}

.loading-text {
  font-size: 16px;
  font-weight: bold;
  color: white;
  /* The text is white, which is fine since the button background is dark */
}

/* Fix for the journal content to ensure its text is visible */
.journal-content {
  flex: 1;
  padding: 15px;
  /* Restored padding that was commented out */
  overflow-y: scroll;
  background-color: #ffffff;
  /* Explicitly set background to white */
}

.markdown-content {
  width: 100%;
  /* Restored width that was commented out */
  color: #333;
  /* Explicitly set text color to dark for better visibility */
}

/* 以下是预览弹窗和Markdown样式，保持不变 */
.journal-modal {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.6);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.journal-container {
  width: 90%;
  height: 80%;
  background-color: white;
  border-radius: 10px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.journal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px;
  border-bottom: 1px solid #eee;
}

.journal-title {
  font-size: 18px;
  font-weight: bold;
  color: #333;
}

.journal-close {
  font-size: 22px;
  color: #999;
  padding: 5px;
}

/* .journal-content {
  flex: 1;
  padding: 15px; 
  overflow-y: scroll;
} */

.journal-actions {
  display: flex;
  border-top: 1px solid #eee;
  padding: 10px 15px;
}

.journal-btn {
  flex: 1;
  margin: 0 5px;
  background-color: #f0f0f0;
  color: #333;
  border-radius: 5px;
  font-size: 14px;
}

.journal-btn.primary {
  background-color: #8b6b4a;
  color: white;
}

.journal-image-container {
  margin: 15px 0;
  text-align: center;
}

.journal-image {
  width: 100%;
  max-height: 300px;
  border-radius: 8px;
  object-fit: cover;
}

/* 添加Markdown样式 */
/* .markdown-content {
  width: 100%; 
} */

.markdown-content h1,
.markdown-content h2,
.markdown-content h3,
.markdown-content h4,
.markdown-content h5,
.markdown-content h6 {
  margin-top: 16px;
  margin-bottom: 8px;
  font-weight: 600;
  line-height: 1.25;
}

.markdown-content h1 {
  font-size: 20px;
}

.markdown-content h2 {
  font-size: 18px;
}

.markdown-content h3 {
  font-size: 16px;
}

.markdown-content p {
  margin-bottom: 10px;
}

.markdown-content ul,
.markdown-content ol {
  margin-bottom: 10px;
  padding-left: 20px;
}

.markdown-content ul {
  list-style-type: disc;
}

.markdown-content ol {
  list-style-type: decimal;
}

.markdown-content li {
  margin-bottom: 5px;
}

.markdown-content code {
  background-color: #f1f1f1;
  padding: 2px 4px;
  border-radius: 3px;
  font-family: monospace;
}

.markdown-content pre {
  background-color: #f6f8fa;
  padding: 10px;
  border-radius: 5px;
  overflow-x: auto;
  margin-bottom: 10px;
}

.markdown-content blockquote {
  border-left: 3px solid #dfe2e5;
  padding-left: 10px;
  color: #6a737d;
  margin: 0 0 10px;
}

.markdown-content a {
  color: #8b6b4a;
  text-decoration: underline;
}

.markdown-content img {
  max-width: 100%;
  margin: 10px 0;
  border-radius: 8px;
}

.journal-image-container {
  margin: 15px 0;
  text-align: center;
}

.journal-image {
  width: 100%;
  max-height: 300px;
  border-radius: 8px;
  object-fit: cover;
}
</style>
